[Android] Dagger2 導入してみた
Dagger2の導入
appのbuild.gradleを修正します。
apply plugin: 'android-apt' dependencies { ... compile 'com.google.dagger:dagger:2.2' apt 'com.google.dagger:dagger-compiler:2.2' ... }
Dagger2 基本構成
実装クラス
DIして利用するクラスです
public interface Sample { void greeting(); } public class SampleImpl implements Sample { @Override void greeting() { Log.d("tag", "hello"); } }
Module
DIするクラスを指定する
@Module public class SampleModule { @Provides SampleImpl provideSampleImpl() { return new SampleImpl(); } }
Component
DIさせる対象を設定する
@Component(modules = SampleModule.class) public interface ActivityComponent { // MainActivityのメンバにinjectする // inject対象を引数にすることで、自動生成されるクラスのメソッド内でメンバへの注入処理が実装される // injectというメソッド名である必要はないが、用途を明確にするために推奨している void inject(MainActivity activity); }
ビルドすると、DaggerActivityComponentが生成されている
public class MainActivity extends Activity { @Inject Sample mSample; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); DaggerActivityComponent.create().inject(this); // mSampleにSampleImplが注入されている mSample.greeting(); } }
少し応用
Dagger2には上記以外の要素として
- Subcomponent
- dependencies
- Scope(Singleton)
といったものが存在する。(Lazyとかはまた別の機会で・・・)
SubComponent
- Componentの親子関係を指定できる
- 親Componentに子Componentを戻り値としたメソッドを用意する
- つまり、親から子を指定する。
- 子のDagger○○Componentは生成されないので、親のメソッドを利用して取得する
- Scopeを分ける時などに利用
dependencies
- Componentの依存関係を指定できる(親子と同じ)
- 子Componentに依存先を記載する
- 子から親を指定する
- 子がDIに必要としているクラスは親に記載する
- Scopeを分ける時などに利用
Scope
対象Component内にて、一意のインスタンスを供給する
(e.g., AppComponent内でOkHttpClientのインスタンスを使い回す)
@SingletonはDagger2が用意してくれているScopeにすぎない
あとがき
Dagger2はDIを導入する道具にすぎないので、
アプリを作る際には、どのような構成にするか・どこでDIを利用するか、などを決めていくことが重要だと感じました。
Dagger2のややこしさに惑わされ手段と目的が入れ替わることのないように注意したいです。